package homework.tcp;

import java.io.*;
import java.net.Socket;
import java.net.SocketException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Set;

/**
 * 这是一个转发消息的线程类
 * 通过接客户端的消息，然后转发给指定客户端
 */
public class Forward implements Runnable {

    //线程停止标识
    private boolean b = true;

    //储存当前线程用户名
    private String user;

    //储存当前用户要和哪个客户端对话
    private String she;

    //储存当前线程客户端的Socket
    private Socket socket;

    //存储所有用户名和Socket
    private static HashMap<String, Socket> map = new HashMap<>();

    //当前系统时间
    private Date date;

    private StringBuffer time = new StringBuffer();

    //格式化系统时间
    private static final SimpleDateFormat sm = new SimpleDateFormat("HH:mm:ss");


    public Forward(Socket socket) {
        this.socket = socket;
    }


    @Override
    public void run() {
        char[] c;
        InputStream inputStream = null;
        OutputStream outputStream = null;
        BufferedReader reader = null;
        BufferedWriter writer = null;
        try {
            //客户端第一次连接进入需要创建用户名,并保存map中
            c = new char[1024];
            inputStream = this.socket.getInputStream();
            reader = new BufferedReader(new InputStreamReader(inputStream, "UTF-8"));
            reader.read(c);
            String user = new String(c).trim();
            //判断是否用户名已存在
            if (map.get(user) == null) {
                this.user = user;
                map.put(user, this.socket);
                System.out.println(user + "客户端已连接服务器...");
                // [ymk]:已进入聊天室!
                send("[系统]:" + this.user + "已进入聊天室!\n");
                send("[系统]:当前人数" + map.size());
            } else {

            }

            while (b) {
                inputStream = this.socket.getInputStream();
                c = new char[1024];
                reader = new BufferedReader(new InputStreamReader(inputStream, "UTF-8"));
                reader.read(c);
                String line = new String(c).trim();
                //判断是否有消息需要转发
                if (line != null && line.length() > 0) {
                    //查询当前人数总和
                    if (line.equals("size")) {
                        outputStream = this.socket.getOutputStream();
                        writer = new BufferedWriter(new OutputStreamWriter(outputStream));
                        // [私聊] ymk:在干啥呢?
                        writer.write("[系统]:当前聊天室人数" + this.map.size());
                        writer.flush();
                        continue;
                    }

                    //判断是否要关闭私聊，进入公共聊天室
                    if (line.equals("close")) {
                        this.she = null;
                        outputStream = socket.getOutputStream();
                        writer = new BufferedWriter(new OutputStreamWriter(outputStream));
                        writer.write("已关闭私聊，进入公共聊天室!\n");
                        writer.flush();
                        continue;
                    }

                    //判断是否有私聊对象
                    if (this.she != null && !this.she.equals("")) {
                        Socket socket = map.get(this.she);
                        outputStream = socket.getOutputStream();
                        writer = new BufferedWriter(new OutputStreamWriter(outputStream));
                        // [私聊] ymk:在干啥呢?
                        //给对方发送
                        writer.write("[私聊] " + this.user + ":" + line);
                        writer.flush();

                        //自己控制台也发送一遍
                        outputStream = this.socket.getOutputStream();
                        writer = new BufferedWriter(new OutputStreamWriter(outputStream));
                        writer.write("[私聊] " + this.user + ":" + line);
                        writer.flush();
                        continue;
                    }

                    //判断当前语句是否为进行私密聊天的指令
                    if (line.indexOf("@@") != -1) {
                        this.she = line.substring(2);
                        outputStream = this.socket.getOutputStream();
                        writer = new BufferedWriter(new OutputStreamWriter(outputStream, "UTF-8"));
                        writer.write("和" + this.she + "连接成功了呢!快点说话吧\n");
                        writer.flush();
                        continue;
                    }


                    date = new Date();
                    this.time = new StringBuffer(this.sm.format(date));
                    send(time + " [" + this.user + "]: " + line);

                }
            }
        } catch (SocketException e) {
            System.out.println("Socket关闭异常");
        } catch (Exception e) {
            System.out.println("转发消息异常");
        } finally {
            map.remove(this.user);
            b = false;
            try {
                reader.close();
                writer.close();
                inputStream.close();
                outputStream.close();
                socket.close();
            } catch (Exception e) {
                System.out.println("关闭run中的流异常");
            }
        }
    }


    /**
     * @return 注意，从socket中获取的流不能关闭，不然下次再次获取就会Socket close 异常
     * if (writer != null) writer.close();
     * if (out != null) writer.close();
     */
    private boolean send(String line) {
        Set<String> users = map.keySet();
        OutputStream out = null;
        BufferedWriter writer = null;
        try {
            for (String user : users) {
                //if (this.user.equals(user)) continue;
                Socket newSocket = map.get(user);
                out = newSocket.getOutputStream();
                writer = new BufferedWriter(new OutputStreamWriter(out, "UTF-8"));
                writer.write(line);
                writer.flush();
            }
        } catch (Exception e) {
            System.out.println(this.user + "进入聊天室消息发送失败!");
        }
        return false;
    }

    //建立私聊
    private boolean whisper() {

        return false;
    }
}
